package fr.mywiki.view.array;

import java.util.ArrayList;
import java.util.List;

import fr.mywiki.business.account.AccountLite;
import fr.mywiki.business.entry.EntryLite;
import fr.mywiki.business.entry.meta.EntryModel;
import fr.mywiki.view.array.cell.CellType;
import fr.mywiki.view.array.cell.StringPropertyDisplayer;
import fr.mywiki.view.array.cell.account.FullUserStructure;
import fr.mywiki.view.array.cell.account.ProfileStringDisplayer;
import fr.mywiki.view.array.cell.entry.LastAuthorDisplayer;
import fr.mywiki.view.array.cell.entry.LastModifDateDisplayer;
import fr.mywiki.view.array.cell.entry.NumberOfVersionsDisplayer;
import fr.mywiki.view.array.cell.entry.WikiEntryDisplayer;
import fr.mywiki.view.array.sort.SortType;

/**
 * What defines a generic object array.
 */
public class ArrayDefinition {
	/** Number of objects by page */
	private int objectsByPage;

	/** Type of sort done on the array */
	private SortType sortType;
	
	/**
	 * <code>ArrayList</code> of <code>ArrayColumn</code> objects, containing
	 * information about the way to display elements of a column
	 */
	private ArrayList columns;
	
	/** Is the column width automatic ? */
	private boolean autoSize;
	
	/** What do we display if there is no element ? */
	private String noElementMessage;

	/** Constructor, builds an empty array definition : 0 column. */
	public ArrayDefinition() {
		objectsByPage = 10;
		sortType = null;
		columns = new ArrayList();
		autoSize = true;
		noElementMessage = "No element";
	}
	
	/**
	 * Adds a column with the specified data.
	 * 
	 * @param title
	 *          title of the column
	 * @param type
	 *          type of the column
	 * @param size
	 *          size of the column
	 */
	public void addColumn(String title, CellType type, int size) {
		columns.add(new ArrayColumn(title,type,size));
	}

	/**
	 * Adds a column with the specified data.
	 * 
	 * @param title
	 *          title of the column
	 * @param type
	 *          type of the column
	 */
	public void addColumn(String title, CellType type) {
		columns.add(new ArrayColumn(title,type));
	}
	
	public int getObjectsByPage() {
		return objectsByPage;
	}

	public void setObjectsByPage(int objectsByPage) {
		this.objectsByPage = objectsByPage;
	}

	public SortType getSortType() {
		return sortType;
	}

	public void setSortType(SortType sortType) {
		this.sortType = sortType;
	}

	public boolean isAutoSize() {
		return autoSize;
	}

	public void setAutoSize(boolean autoSize) {
		this.autoSize = autoSize;
	}
	
	/**
	 * Returns the number of columns.
	 * @return the size of columnTitles
	 */
	public int getColumnNumber() {
		return columns.size();
	}
	
	/**
	 * Builds a standard <code>ArrayDefinition</code> for a array with 
	 * @param typeEnt
	 * @return
	 */
	public static ArrayDefinition getArrayDefinition(String typeEnt) {
		ArrayDefinition arrayDef = new ArrayDefinition();
		
		if(EntryLite.TYPE_ENT.equals(typeEnt)) {
			// Building a array of entries.
			// Columns : title | beginning of the entry text | last modification |
			// last author | number of versions.
			arrayDef.addColumn("Title", new StringPropertyDisplayer(
					EntryLite.FIELD_TITLE,true));
			arrayDef.addColumn("Content", new WikiEntryDisplayer(5));
			arrayDef.addColumn("Last modification", new LastModifDateDisplayer());
			arrayDef.addColumn("Last author", new LastAuthorDisplayer());
			arrayDef.addColumn("Number of versions", new NumberOfVersionsDisplayer());
		} else if (AccountLite.TYPE_ENT.equals(typeEnt)) {
			// Building a array of users.
			// Columns : login | profile | structure
			arrayDef.addColumn("Login", new StringPropertyDisplayer(
					AccountLite.FIELD_LOGIN, true));
			arrayDef.addColumn("Profile", new ProfileStringDisplayer());
			arrayDef.addColumn("Structure",new FullUserStructure());
		} else if(EntryModel.TYPE_ENT.equals(typeEnt)) {
			// Building a array of entry models
			// One single column : clickable name.
			arrayDef.addColumn("Name", new StringPropertyDisplayer(EntryModel.FIELD_NAME,true));
		}
		
		return arrayDef;
	}

	public String getNoElementMessage() {
		return noElementMessage;
	}

	public void setNoElementMessage(String noElementMessage) {
		this.noElementMessage = noElementMessage;
	}

	public List getColumns() {
		return columns;
	}
	
	/**
	 * Returns a list containing all the column titles.
	 * 
	 * @return a <code>List</code> of <code>String</code>
	 */
	public List getColumnTitles() {
		List res = new ArrayList();
		for(int i=0;i<columns.size();i++)
			res.add(((ArrayColumn)columns.get(i)).getTitle());
		return res;
	}
	
	/**
	 * Returns a list containing all the column types.
	 * 
	 * @return a <code>List</code> of <code>CellType</code>
	 */
	public List getColumnTypes() {
		List res = new ArrayList();
		for(int i=0;i<columns.size();i++)
			res.add(((ArrayColumn)columns.get(i)).getType());
		return res;
	}
}
